from common import *


class ResultListEntity(list):
    def __init__(self):
        super().__init__()
        self.lock = RLock()
        self.select_item = None
        self.select_num = 0
        self.select_item_num = 0
        self.pos = 0
        self.item_count = 0

    def __get_select_item__(self):
        if self.select_item is None and len(self) > 0:
            self.select_item = self[0]
        return self.select_item

    def add(self, list_val):
        with self.lock:
            if len(list_val) > 0:
                self.append(list_val)
                self.item_count += len(list_val)

    def get_count(self):
        with self.lock:
            return self.item_count

    def has_next(self):
        return self.pos < self.get_count()

    def next(self):
        with self.lock:
            if self.has_next():
                select_val = self.__get_select_item__()
                rtn = select_val[self.select_item_num]
                self.select_item_num += 1
                self.pos += 1
                if self.select_item_num >= len(self.select_item):
                    self.select_num += 1
                    self.select_item_num = 0
                self.select_item = self[self.select_num] if self.select_num < len(self) else None
                return rtn
        return None


class IndexBaseEntity:
    def __init__(self, group_name, init=None):
        self.group_name = group_name
        self.status = 0
        self.s_front = 0
        self.s_back = 0
        self.str_val = 0
        self.i_start = 0
        self.i_end = 0
        self.d_start = 0
        self.d_end = 0
        self.pos = 0
        if init is not None:
            self.status, self.s_front, self.s_back, self.str_val, self.i_start, self.i_end, self.d_start, self.d_end, self.pos = init

    def get_data(self):
        return self.status, self.s_front, self.s_back, self.str_val, self.i_start, self.i_end, self.d_start, self.d_end, self.pos


class FindIndexCollectEntity:
    def __init__(self, group_name, key_value, tp):
        self.group_name = group_name
        self.key_value = key_value
        self.tp = tp
        self.status = 0
        self.s_front = 0
        self.s_back = 0
        self.str_val = 0
        self.i_start = 0
        self.i_end = 0
        self.d_start = 0
        self.d_end = 0
        self.pos = 0
        self.__bind_value__()

    def __bind_value__(self):
        status, s_front, s_back, str_val, i_start, i_end, d_start, d_end, pos = MemoryFileOpt.find_collect_next(
            self.group_name, self.s_front, self.s_back, self.key_value, self.tp)
        self.status = status
        self.s_front = s_front
        self.s_back = s_back
        self.str_val = str_val
        self.i_start = i_start
        self.i_end = i_end
        self.d_start = d_start
        self.d_end = d_end
        self.pos = pos

    def get_data(self):
        index = IndexBaseEntity(self.group_name)
        index.status = self.status
        index.s_front = self.s_front
        index.s_back = self.s_back
        index.str_val = self.str_val
        index.i_start = self.i_start
        index.i_end = self.i_end
        index.d_start = self.d_start
        index.d_end = self.d_end
        index.pos = self.pos
        return index

    def next(self):
        self.__bind_value__()

    def has_next(self):
        if SymbolEnum.lt.value == (self.tp & SymbolEnum.lt.value):
            return self.s_back > 0
        else:
            return self.s_front > 0


class DataEntityCollect(list):
    def __init__(self, data_cache=None, call_back=None):
        super().__init__()
        self.call_back = call_back
        self.data_cache = data_cache
        self.read_collect = dict()

    def add(self, index, position, size, data_cache=None):
        callback_status = True
        dc = self.data_cache if data_cache is None else data_cache
        de = DataEntity(index, dc, self.__get_read_collect__(dc))
        de.size = size
        de.position = position
        if self.call_back is not None:
            callback_status = self.call_back(de)
        self.append(de)
        return callback_status

    def __get_read_collect__(self, data_cache):
        if data_cache.group_name not in self.read_collect:
            self.read_collect[data_cache.group_name] = data_cache.create_fs()
        return self.read_collect[data_cache.group_name]


class DataEntity:

    def __init__(self, index, data_cache, read_collect):
        self.position = 0
        self.size = 0
        self.index = index
        self.data_cache = data_cache
        self.read_collect = read_collect

    def get_data(self):
        fs = self.read_collect.add_fs(self.position)
        return self.data_cache.read(self.position, self.size, fs)


class FieldItemEntity:
    def __init__(self):
        self.name = None
        self.value = None
        self.field_key = None
        # self.index_key = None
        self.field_text = None
        self.symbol = None
        self.name_key = None
        self.base_name = None
        self.base_value = None
        self.is_num = NumberType.NOT
        # self.value_key = None


class FieldEntity:

    def __init__(self):
        self.field_list = list()
        self.key = None

    def add(self, field_name, field_value, symbol=SymbolEnum.eq):
        field_item = FieldItemEntity()
        field_item.is_num = is_num(field_value)
        field_item.symbol = symbol
        field_item.name = urllib.parse.quote(field_name)
        field_item.value = urllib.parse.quote(field_value)
        field_item.field_text = "%s=%s" % (field_item.name, field_item.value)
        field_item.field_key = create_key(field_value)
        # field_item.index_key = create_index_key(field_item.field_text)
        field_item.name_key = create_key(field_item.name)
        field_item.base_name = field_name
        field_item.base_value = field_value
        # field_item.value_key = create_key(field_item.value)

        self.field_list.append(field_item)
        return field_item

    def set_key(self, field):
        self.key = field

    def get_key(self):
        if self.key is None:
            self.key = self.field_list[0]
        return self.key


class ConditionEntity:
    def __init__(self, name, symbol, val):
        self.symbol = symbol
        self.name = name
        self.val = val
